SlideShare a Scribd company logo
1 of 31
Download to read offline
Rcpp: Seamless R and C++

     Dirk Eddelbuettel         Romain François
          edd@debian.org       romain@r-enthusiasts.com




useR! 2010, 21 July 2010, NIST, Gaithersburg, Maryland, USA
Fine for Indiana Jones
Le viaduc de Millau
Background API Sugar Modules




                                     Plat du jour

1   Appetizers : Some background on R and C++

2   Main course : The Rcpp API

3   Desert : Rcpp sugar

4   Coffee : Rcpp modules




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Examples

R support for C/C++


      R is a C program
      R supports C++ out of the box, just use a .cpp file extension
      R exposes a API based on low level C functions and MACROS.
      R provides several calling conventions to invoke compiled code.


  SEXP foo( SEXP x1, SEXP x2 ){
     ...
  }

  R> .Call( "foo", 1:10, rnorm(10) )




          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Examples

.Call example
  #include <R.h>
  #include <Rdefines.h>
  extern "C" SEXP vectorfoo(SEXP a, SEXP b){
    int i, n;
    double *xa, *xb, *xab; SEXP ab;
    PROTECT(a = AS_NUMERIC(a));
    PROTECT(b = AS_NUMERIC(b));
    n = LENGTH(a);
    PROTECT(ab = NEW_NUMERIC(n));
    xa=NUMERIC_POINTER(a); xb=NUMERIC_POINTER(b);
    xab = NUMERIC_POINTER(ab);
    double x = 0.0, y = 0.0 ;
    for (i=0; i<n; i++) xab[i] = 0.0;
    for (i=0; i<n; i++) {
       x = xa[i]; y = xb[i];
       res[i] = (x < y) ? x*x : -(y*y);
      }
      UNPROTECT(3);
      return(ab);
  }

           Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Examples

.Call example: character vectors


  R> c( "foo", "bar" )

  #include <R.h>
  #include <Rdefines.h>
  extern "C" SEXP foobar(){
    SEXP res = PROTECT(allocVector(STRSXP, 2));
    SET_STRING_ELT( res, 0, mkChar( "foo" ) ) ;
    SET_STRING_ELT( res, 1, mkChar( "bar" ) ) ;
    UNPROTECT(1) ;
    return res ;
  }




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Examples

.Call example: calling an R function

  R> eval( call( "rnorm", 3L, 10.0, 20.0 ) )


  #include <R.h>
  #include <Rdefines.h>
  extern "C" SEXP callback(){
    SEXP call = PROTECT( LCONS( install("rnorm"),
        CONS( ScalarInteger( 3 ),
          CONS( ScalarReal( 10.0 ),
           CONS( ScalarReal( 20.0 ), R_NilValue )
         )
      )
    ) );
    SEXP res = PROTECT(eval(call, R_GlobalEnv)) ;
    UNPROTECT(2) ;
    return res ;
  }

        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
The Rcpp API
Background API Sugar Modules          Overview Example Conversion

The Rcpp API



     Encapsulation of R objects (SEXP) into C++ classes:
     NumericVector, IntegerVector, ..., Function,
     Environment, Language, ...

     Conversion from R to C++ : as

     Conversion from C++ to R : wrap

     Interoperability with the Standard Template Library (STL)




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Example Conversion

The Rcpp API : classes


            Rcpp class                                    R typeof
     Integer(Vector|Matrix)                      integer vectors and matrices
     Numeric(Vector|Matrix)                              numeric ...
     Logical(Vector|Matrix)                              logical ...
    Character(Vector|Matrix)                            character ...
       Raw(Vector|Matrix)                                  raw ...
     Complex(Vector|Matrix)                              complex ...
               List                              list (aka generic vectors) ...
   Expression(Vector|Matrix)                           expression ...
           Environment                                 environment
            Function                                     function
               XPtr                                    externalptr
            Language                                     language
                S4                                           S4
                ...                                          ...

        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Example Conversion

The Rcpp API : example


  SEXP foo( SEXP xs, SEXP ys ){
      Rcpp::NumericVector xx(xs), yy(ys) ;
      int n = xx.size() ;
      Rcpp::NumericVector res( n ) ;
      double x = 0.0, y = 0.0 ;
      for (int i=0; i<n; i++) {
           x = xx[i];
           y = yy[i];
           res[i] = (x < y) ? x*x : -(y*y);
      }
      return res ;
  }




          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Example Conversion

The Rcpp API : example


  using namespace Rcpp ;
  SEXP bar(){
       std::vector<double> z(10) ;
       List res = List::create(
          _["foo"] = NumericVector::create(1,2),
          _["bar"] = 3,
          _["bla"] = "yada yada",
          _["blo"] = z
          ) ;
       res.attr("class") = "myclass" ;
       return res ;
  }




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Example Conversion

The Rcpp API : Example from RQuantLib

  using namespace Rcpp;
  using namespace std;
  using namespace boost;
  RcppExport SEXP
  QL_isBusinessDay(SEXP calSexp, SEXP dateSexp) {
    shared_ptr<Calendar>
         pcal(getCalendar(as<string>(calSexp)));
    DateVector dates = DateVector(dateSexp);
    int n = dates.size();
    vector<int> bizdays(n);
    for (int i=0; i<n; i++) {
       QuantLib::Date day( dateFromR(dates[i]) );
       bizdays[i] = pcal->isBusinessDay(day);
      }
      return wrap(bizdays);
  }

          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules        Overview Example Conversion

The Rcpp API : conversion from R to C++

  Rcpp::as<T> handles conversion from SEXP to T.

  template <typename T> T as( SEXP m_sexp)
      throw(not_compatible) ;

  T can be:
      primitive type : int, double, bool, long, std::string
      any type that has a constructor taking a SEXP
      ... that specializes the as template
      ... that specializes the Exporter class template
      containers from the STL
  more details in the Rcpp-extending vignette.


          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules        Overview Example Conversion

The Rcpp API : conversion from C++ to R

  Rcpp::wrap<T> handles conversion from T to SEXP.

  template <typename T>
  SEXP wrap( const T& object ) ;

  T can be:
      primitive type : int, double, bool, long, std::string
      any type that has a an operator SEXP
      ... that specializes the wrap template
      ... that has a nested type called iterator and member
      functions begin and end
      containers from the STL vector<T>, list<T>,
      map<string,T>, etc ... (where T is itself wrappable)
  more details in the Rcpp-extending vignette.

          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Example Conversion

The Rcpp API : conversion examples

  typedef std::vector<double> Vec ;
  int x_ = as<int>( x ) ;
  double y_ = as<double>( y_ ) ;
  VEC z_ = as<VEC>( z_ ) ;

  wrap( 1 ) ; // INTSXP
  wrap( "foo" ) ; // STRSXP

  typedef std::map<std::string,Vec> Map ;
  Map foo( 10 ) ;
  Vec f1(4) ;
  Vec f2(10) ;
  foo.insert( "x", f1 ) ;
  foo.insert( "y", f2 ) ;
  wrap( foo ) ; // named list of numeric vectors


         Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview Example Conversion

The Rcpp API : implicit conversion examples


  Environment env = ... ;
  List list = ... ;
  Function rnorm( "rnorm") ;

  // implicit calls to as
  int x = env["x"] ;
  double y = list["y"];

  // implicit calls to wrap
  rnorm( 100, _["mean"] = 10 ) ;
  env["x"] = 3;
  env["y"] = "foo" ;
  List::create( 1, "foo", 10.0, false ) ;




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Rcpp sugar
Background API Sugar Modules          Motivation Example Contents Performance

Sugar : motivation


  int n = x.size() ;
   NumericVector res1( n ) ;
   double x_ = 0.0, y_ = 0.0 ;
   for( int i=0; i<n; i++){
           x_ = x[i] ;y_ = y[i] ;
           if( R_IsNA(x_) || R_IsNA(y_) ){
                res1[i] = NA_REAL;
           } else if( x_ < y_ ){
                res1[i] = x_ * x_ ;
           } else {
                res1[i] = -( y_ * y_) ;
             }
      }



          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Motivation Example Contents Performance

Sugar : motivation


  We missed the R syntax :
  R> ifelse( x < y, x*x, -(y*y) )




         Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Motivation Example Contents Performance

Sugar : motivation


  We missed the R syntax :
  R> ifelse( x < y, x*x, -(y*y) )


  sugar brings it into C++

  SEXP foo( SEXP xx, SEXP yy){
      NumericVector x(xx), y(yy) ;
      return ifelse( x < y, x*x, -(y*y) ) ;
  }




          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Motivation Example Contents Performance

Sugar : another example



  double square( double x){
    return x*x ;
  }

  SEXP foo( SEXP xx ){
    NumericVector x(xx) ;
    return sapply( x, square ) ;
  }




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Motivation Example Contents Performance

Sugar : contents

      logical operators: <, >, <=, >=, ==, !=
      arithmetic operators: +, -, *, /
      functions on vectors: abs, all, any, ceiling, diag,
      diff, exp, head, ifelse, is_na, lapply, pmin, pmax,
      pow, rep, rep_each, rep_len, rev, sapply,
      seq_along, seq_len, sign, tail
      functions on matrices: outer, col, row, lower_tri,
      upper_tri, diag


  Sugar uses Expression Templates (Blitz++, Armadillo, ...) to
  achieve lazy evaluation of expressions.

  More information in the Rcpp-sugar vignette.

          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules              Motivation Example Contents Performance

Sugar : benchmarks




    expression                                               sugar                 R            R / sugar
    any(x*y<0)                                           0.0008771              29.58         33721
    ifelse(x<y,x*x,-(y*y))                               5.217                  35.88             6.879
    sapply(x,square)                                     0.6322                259.4            410.2

  Benchmarks performed on fedora 12 / R 2.12.0 (under development) on a 2 years old dell inspiron 1525 laptop.




                 Dirk Eddelbuettel and Romain François       Seamless R anc C++ Integration @ useR! 2010
Rcpp modules
Background API Sugar Modules          Overview R side

Modules: expose C++ to R


  const char* hello( const std::string& who ){
      std::string result( "hello " ) ;
      result += who ;
      return result.c_str() ;
  }

  RCPP_MODULE(yada){
      using namespace Rcpp ;
      function( "hello", &hello ) ;
  }

  R> yada <- Module( "yada" )
  R> yada$hello( "world" )



        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview R side

Modules: expose C++ classes to R

  class World {
  public:
       World() : msg("hello"){}
       void set(std::string msg) {
           this->msg = msg;
      }
      std::string greet() {
          return msg;
      }
  private:
       std::string msg;
  };

  void clearWorld( World* w){
      w->set( "" ) ;
  }

          Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview R side

Modules: expose C++ classes to R



  RCPP_MODULE(yada){
      using namespace Rcpp ;

      class_<World>( "World" )
          .method( "greet", &World::greet )
          .method( "set", &World::set )
          .method( "clear", &clearWorld )
      ;

  }




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Background API Sugar Modules          Overview R side

Modules: on the R side


  R> w <- new( yada$World )
  R> w$greet()
  [1] "hello"

  R> w$set( "hello world")
  R> w$greet()
  [1] "hello world"

  R> w$clear()
  R> w$greet()
  [1] ""




        Dirk Eddelbuettel and Romain François   Seamless R anc C++ Integration @ useR! 2010
Want to learn more ?

  Check the vignettes

  Questions on the Rcpp-devel mailing list

  Hands-on training courses

  Commercial support



Romain François               romain@r-enthusiasts.com
Dirk Eddelbuettel                       edd@debian.org

More Related Content

What's hot

Python Programming - IX. On Randomness
Python Programming - IX. On RandomnessPython Programming - IX. On Randomness
Python Programming - IX. On RandomnessRanel Padon
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lispkyleburton
 
Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) wahab khan
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scalaPiotr Paradziński
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 itiAhmed mar3y
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Sumant Tambe
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with ScalaDenis
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemJohn De Goes
 
C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumlercorehard_by
 
Garbage Collection
Garbage CollectionGarbage Collection
Garbage CollectionEelco Visser
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engineDuoyi Wu
 
Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009Jan Wedekind
 
friends functionToshu
friends functionToshufriends functionToshu
friends functionToshuSidd Singh
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: NotesRoberto Casadei
 

What's hot (20)

Python Programming - IX. On Randomness
Python Programming - IX. On RandomnessPython Programming - IX. On Randomness
Python Programming - IX. On Randomness
 
Idiomatic C++
Idiomatic C++Idiomatic C++
Idiomatic C++
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence)
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scala
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 iti
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
L4 functions
L4 functionsL4 functions
L4 functions
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
 
C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumler
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
 
Garbage Collection
Garbage CollectionGarbage Collection
Garbage Collection
 
Summary of C++17 features
Summary of C++17 featuresSummary of C++17 features
Summary of C++17 features
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009
 
C++11
C++11C++11
C++11
 
friends functionToshu
friends functionToshufriends functionToshu
friends functionToshu
 
Java Script Workshop
Java Script WorkshopJava Script Workshop
Java Script Workshop
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 

Similar to Rcpp: Seemless R and C++

Integrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufIntegrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufRomain Francois
 
Native interfaces for R
Native interfaces for RNative interfaces for R
Native interfaces for RSeth Falcon
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesGanesh Samarthyam
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Chris Adamson
 
Intel JIT Talk
Intel JIT TalkIntel JIT Talk
Intel JIT Talkiamdvander
 
What's new in Apache SystemML - Declarative Machine Learning
What's new in Apache SystemML  - Declarative Machine LearningWhat's new in Apache SystemML  - Declarative Machine Learning
What's new in Apache SystemML - Declarative Machine LearningLuciano Resende
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errorsPVS-Studio
 
Lex (lexical analyzer)
Lex (lexical analyzer)Lex (lexical analyzer)
Lex (lexical analyzer)Sami Said
 
Extend R with Rcpp!!!
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!mickey24
 
SystemML - Declarative Machine Learning
SystemML - Declarative Machine LearningSystemML - Declarative Machine Learning
SystemML - Declarative Machine LearningLuciano Resende
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++Alexander Granin
 
Translate the following CC++ code into MIPS Assembly Codevoid ch.pdf
Translate the following CC++ code into MIPS Assembly Codevoid ch.pdfTranslate the following CC++ code into MIPS Assembly Codevoid ch.pdf
Translate the following CC++ code into MIPS Assembly Codevoid ch.pdffcsondhiindia
 

Similar to Rcpp: Seemless R and C++ (20)

Integrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufIntegrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBuf
 
Rcpp
RcppRcpp
Rcpp
 
R and C++
R and C++R and C++
R and C++
 
Native interfaces for R
Native interfaces for RNative interfaces for R
Native interfaces for R
 
R/C++ talk at earl 2014
R/C++ talk at earl 2014R/C++ talk at earl 2014
R/C++ talk at earl 2014
 
Rcpp11 genentech
Rcpp11 genentechRcpp11 genentech
Rcpp11 genentech
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on Examples
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
Intel JIT Talk
Intel JIT TalkIntel JIT Talk
Intel JIT Talk
 
Rcpp11
Rcpp11Rcpp11
Rcpp11
 
What's new in Apache SystemML - Declarative Machine Learning
What's new in Apache SystemML  - Declarative Machine LearningWhat's new in Apache SystemML  - Declarative Machine Learning
What's new in Apache SystemML - Declarative Machine Learning
 
R and cpp
R and cppR and cpp
R and cpp
 
Monads in Swift
Monads in SwiftMonads in Swift
Monads in Swift
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errors
 
Lex (lexical analyzer)
Lex (lexical analyzer)Lex (lexical analyzer)
Lex (lexical analyzer)
 
Extend R with Rcpp!!!
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language Introduction
 
SystemML - Declarative Machine Learning
SystemML - Declarative Machine LearningSystemML - Declarative Machine Learning
SystemML - Declarative Machine Learning
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
 
Translate the following CC++ code into MIPS Assembly Codevoid ch.pdf
Translate the following CC++ code into MIPS Assembly Codevoid ch.pdfTranslate the following CC++ code into MIPS Assembly Codevoid ch.pdf
Translate the following CC++ code into MIPS Assembly Codevoid ch.pdf
 

More from Romain Francois (14)

R/C++
R/C++R/C++
R/C++
 
dplyr and torrents from cpasbien
dplyr and torrents from cpasbiendplyr and torrents from cpasbien
dplyr and torrents from cpasbien
 
dplyr use case
dplyr use casedplyr use case
dplyr use case
 
dplyr
dplyrdplyr
dplyr
 
user2015 keynote talk
user2015 keynote talkuser2015 keynote talk
user2015 keynote talk
 
SevillaR meetup: dplyr and magrittr
SevillaR meetup: dplyr and magrittrSevillaR meetup: dplyr and magrittr
SevillaR meetup: dplyr and magrittr
 
dplyr
dplyrdplyr
dplyr
 
Data manipulation with dplyr
Data manipulation with dplyrData manipulation with dplyr
Data manipulation with dplyr
 
Rcpp11 useR2014
Rcpp11 useR2014Rcpp11 useR2014
Rcpp11 useR2014
 
Rcpp attributes
Rcpp attributesRcpp attributes
Rcpp attributes
 
Rcpp is-ready
Rcpp is-readyRcpp is-ready
Rcpp is-ready
 
Rcpp
RcppRcpp
Rcpp
 
Object Oriented Design(s) in R
Object Oriented Design(s) in RObject Oriented Design(s) in R
Object Oriented Design(s) in R
 
RProtoBuf: protocol buffers for R
RProtoBuf: protocol buffers for RRProtoBuf: protocol buffers for R
RProtoBuf: protocol buffers for R
 

Rcpp: Seemless R and C++

  • 1. Rcpp: Seamless R and C++ Dirk Eddelbuettel Romain François edd@debian.org romain@r-enthusiasts.com useR! 2010, 21 July 2010, NIST, Gaithersburg, Maryland, USA
  • 3. Le viaduc de Millau
  • 4. Background API Sugar Modules Plat du jour 1 Appetizers : Some background on R and C++ 2 Main course : The Rcpp API 3 Desert : Rcpp sugar 4 Coffee : Rcpp modules Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 5. Background API Sugar Modules Overview Examples R support for C/C++ R is a C program R supports C++ out of the box, just use a .cpp file extension R exposes a API based on low level C functions and MACROS. R provides several calling conventions to invoke compiled code. SEXP foo( SEXP x1, SEXP x2 ){ ... } R> .Call( "foo", 1:10, rnorm(10) ) Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 6. Background API Sugar Modules Overview Examples .Call example #include <R.h> #include <Rdefines.h> extern "C" SEXP vectorfoo(SEXP a, SEXP b){ int i, n; double *xa, *xb, *xab; SEXP ab; PROTECT(a = AS_NUMERIC(a)); PROTECT(b = AS_NUMERIC(b)); n = LENGTH(a); PROTECT(ab = NEW_NUMERIC(n)); xa=NUMERIC_POINTER(a); xb=NUMERIC_POINTER(b); xab = NUMERIC_POINTER(ab); double x = 0.0, y = 0.0 ; for (i=0; i<n; i++) xab[i] = 0.0; for (i=0; i<n; i++) { x = xa[i]; y = xb[i]; res[i] = (x < y) ? x*x : -(y*y); } UNPROTECT(3); return(ab); } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 7. Background API Sugar Modules Overview Examples .Call example: character vectors R> c( "foo", "bar" ) #include <R.h> #include <Rdefines.h> extern "C" SEXP foobar(){ SEXP res = PROTECT(allocVector(STRSXP, 2)); SET_STRING_ELT( res, 0, mkChar( "foo" ) ) ; SET_STRING_ELT( res, 1, mkChar( "bar" ) ) ; UNPROTECT(1) ; return res ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 8. Background API Sugar Modules Overview Examples .Call example: calling an R function R> eval( call( "rnorm", 3L, 10.0, 20.0 ) ) #include <R.h> #include <Rdefines.h> extern "C" SEXP callback(){ SEXP call = PROTECT( LCONS( install("rnorm"), CONS( ScalarInteger( 3 ), CONS( ScalarReal( 10.0 ), CONS( ScalarReal( 20.0 ), R_NilValue ) ) ) ) ); SEXP res = PROTECT(eval(call, R_GlobalEnv)) ; UNPROTECT(2) ; return res ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 10. Background API Sugar Modules Overview Example Conversion The Rcpp API Encapsulation of R objects (SEXP) into C++ classes: NumericVector, IntegerVector, ..., Function, Environment, Language, ... Conversion from R to C++ : as Conversion from C++ to R : wrap Interoperability with the Standard Template Library (STL) Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 11. Background API Sugar Modules Overview Example Conversion The Rcpp API : classes Rcpp class R typeof Integer(Vector|Matrix) integer vectors and matrices Numeric(Vector|Matrix) numeric ... Logical(Vector|Matrix) logical ... Character(Vector|Matrix) character ... Raw(Vector|Matrix) raw ... Complex(Vector|Matrix) complex ... List list (aka generic vectors) ... Expression(Vector|Matrix) expression ... Environment environment Function function XPtr externalptr Language language S4 S4 ... ... Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 12. Background API Sugar Modules Overview Example Conversion The Rcpp API : example SEXP foo( SEXP xs, SEXP ys ){ Rcpp::NumericVector xx(xs), yy(ys) ; int n = xx.size() ; Rcpp::NumericVector res( n ) ; double x = 0.0, y = 0.0 ; for (int i=0; i<n; i++) { x = xx[i]; y = yy[i]; res[i] = (x < y) ? x*x : -(y*y); } return res ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 13. Background API Sugar Modules Overview Example Conversion The Rcpp API : example using namespace Rcpp ; SEXP bar(){ std::vector<double> z(10) ; List res = List::create( _["foo"] = NumericVector::create(1,2), _["bar"] = 3, _["bla"] = "yada yada", _["blo"] = z ) ; res.attr("class") = "myclass" ; return res ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 14. Background API Sugar Modules Overview Example Conversion The Rcpp API : Example from RQuantLib using namespace Rcpp; using namespace std; using namespace boost; RcppExport SEXP QL_isBusinessDay(SEXP calSexp, SEXP dateSexp) { shared_ptr<Calendar> pcal(getCalendar(as<string>(calSexp))); DateVector dates = DateVector(dateSexp); int n = dates.size(); vector<int> bizdays(n); for (int i=0; i<n; i++) { QuantLib::Date day( dateFromR(dates[i]) ); bizdays[i] = pcal->isBusinessDay(day); } return wrap(bizdays); } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 15. Background API Sugar Modules Overview Example Conversion The Rcpp API : conversion from R to C++ Rcpp::as<T> handles conversion from SEXP to T. template <typename T> T as( SEXP m_sexp) throw(not_compatible) ; T can be: primitive type : int, double, bool, long, std::string any type that has a constructor taking a SEXP ... that specializes the as template ... that specializes the Exporter class template containers from the STL more details in the Rcpp-extending vignette. Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 16. Background API Sugar Modules Overview Example Conversion The Rcpp API : conversion from C++ to R Rcpp::wrap<T> handles conversion from T to SEXP. template <typename T> SEXP wrap( const T& object ) ; T can be: primitive type : int, double, bool, long, std::string any type that has a an operator SEXP ... that specializes the wrap template ... that has a nested type called iterator and member functions begin and end containers from the STL vector<T>, list<T>, map<string,T>, etc ... (where T is itself wrappable) more details in the Rcpp-extending vignette. Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 17. Background API Sugar Modules Overview Example Conversion The Rcpp API : conversion examples typedef std::vector<double> Vec ; int x_ = as<int>( x ) ; double y_ = as<double>( y_ ) ; VEC z_ = as<VEC>( z_ ) ; wrap( 1 ) ; // INTSXP wrap( "foo" ) ; // STRSXP typedef std::map<std::string,Vec> Map ; Map foo( 10 ) ; Vec f1(4) ; Vec f2(10) ; foo.insert( "x", f1 ) ; foo.insert( "y", f2 ) ; wrap( foo ) ; // named list of numeric vectors Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 18. Background API Sugar Modules Overview Example Conversion The Rcpp API : implicit conversion examples Environment env = ... ; List list = ... ; Function rnorm( "rnorm") ; // implicit calls to as int x = env["x"] ; double y = list["y"]; // implicit calls to wrap rnorm( 100, _["mean"] = 10 ) ; env["x"] = 3; env["y"] = "foo" ; List::create( 1, "foo", 10.0, false ) ; Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 20. Background API Sugar Modules Motivation Example Contents Performance Sugar : motivation int n = x.size() ; NumericVector res1( n ) ; double x_ = 0.0, y_ = 0.0 ; for( int i=0; i<n; i++){ x_ = x[i] ;y_ = y[i] ; if( R_IsNA(x_) || R_IsNA(y_) ){ res1[i] = NA_REAL; } else if( x_ < y_ ){ res1[i] = x_ * x_ ; } else { res1[i] = -( y_ * y_) ; } } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 21. Background API Sugar Modules Motivation Example Contents Performance Sugar : motivation We missed the R syntax : R> ifelse( x < y, x*x, -(y*y) ) Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 22. Background API Sugar Modules Motivation Example Contents Performance Sugar : motivation We missed the R syntax : R> ifelse( x < y, x*x, -(y*y) ) sugar brings it into C++ SEXP foo( SEXP xx, SEXP yy){ NumericVector x(xx), y(yy) ; return ifelse( x < y, x*x, -(y*y) ) ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 23. Background API Sugar Modules Motivation Example Contents Performance Sugar : another example double square( double x){ return x*x ; } SEXP foo( SEXP xx ){ NumericVector x(xx) ; return sapply( x, square ) ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 24. Background API Sugar Modules Motivation Example Contents Performance Sugar : contents logical operators: <, >, <=, >=, ==, != arithmetic operators: +, -, *, / functions on vectors: abs, all, any, ceiling, diag, diff, exp, head, ifelse, is_na, lapply, pmin, pmax, pow, rep, rep_each, rep_len, rev, sapply, seq_along, seq_len, sign, tail functions on matrices: outer, col, row, lower_tri, upper_tri, diag Sugar uses Expression Templates (Blitz++, Armadillo, ...) to achieve lazy evaluation of expressions. More information in the Rcpp-sugar vignette. Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 25. Background API Sugar Modules Motivation Example Contents Performance Sugar : benchmarks expression sugar R R / sugar any(x*y<0) 0.0008771 29.58 33721 ifelse(x<y,x*x,-(y*y)) 5.217 35.88 6.879 sapply(x,square) 0.6322 259.4 410.2 Benchmarks performed on fedora 12 / R 2.12.0 (under development) on a 2 years old dell inspiron 1525 laptop. Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 27. Background API Sugar Modules Overview R side Modules: expose C++ to R const char* hello( const std::string& who ){ std::string result( "hello " ) ; result += who ; return result.c_str() ; } RCPP_MODULE(yada){ using namespace Rcpp ; function( "hello", &hello ) ; } R> yada <- Module( "yada" ) R> yada$hello( "world" ) Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 28. Background API Sugar Modules Overview R side Modules: expose C++ classes to R class World { public: World() : msg("hello"){} void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } private: std::string msg; }; void clearWorld( World* w){ w->set( "" ) ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 29. Background API Sugar Modules Overview R side Modules: expose C++ classes to R RCPP_MODULE(yada){ using namespace Rcpp ; class_<World>( "World" ) .method( "greet", &World::greet ) .method( "set", &World::set ) .method( "clear", &clearWorld ) ; } Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 30. Background API Sugar Modules Overview R side Modules: on the R side R> w <- new( yada$World ) R> w$greet() [1] "hello" R> w$set( "hello world") R> w$greet() [1] "hello world" R> w$clear() R> w$greet() [1] "" Dirk Eddelbuettel and Romain François Seamless R anc C++ Integration @ useR! 2010
  • 31. Want to learn more ? Check the vignettes Questions on the Rcpp-devel mailing list Hands-on training courses Commercial support Romain François romain@r-enthusiasts.com Dirk Eddelbuettel edd@debian.org